//
//  WJAudioPlayView.h.m
//  WJBSApp
//
//  Created by dllo on 16/7/21.
//  Copyright © 2016年 王景伟. All rights reserved.
//

#import "WJAudioPlayView.h"
#import <AVFoundation/AVFoundation.h>
#import "WJAudioBelowView.h"

//宏定义   角度转弧度
#define angleToRadian(x) (x/180.0*M_PI)

@interface WJAudioPlayView ()
@property (nonatomic, strong) UIButton *roatBut;
@property (nonatomic, strong) WJAudioBelowView *rightView;
@property (nonatomic, strong) id progressObserver;
@property (nonatomic, assign) CGFloat totalTime;
@property (nonatomic, strong) NSString *strUrl;
@property (nonatomic, assign) BOOL isPlay;
@property (nonatomic, strong) AVPlayer *player;
@property (nonatomic, strong) AVPlayerItem *playerItem;
// 设置一个私有的定时器
@property (nonatomic,strong) CADisplayLink *link;
@end

@implementation WJAudioPlayView

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [self.player removeTimeObserver:self.progressObserver];
    [self removeObserverFromPlayerItem:self.player.currentItem];
}

/** 销毁View */
- (void)resetAudioPlayView {
    [self.player pause];
    [self removeObserverFromPlayerItem:self.player.currentItem];
    [self.player removeTimeObserver:self.progressObserver];
    [self removeFromSuperview];
}

+ (WJAudioPlayView *)sharedPlayView {
    static dispatch_once_t once;
    static id instance;
    dispatch_once(&once, ^{
        instance = [[self alloc]initWithFrame:CGRectMake(0, BSViewH - 50, WIDTH, 50)];
    });
    return instance;
}

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self createView];
    }
    return self;
}

- (void)createView {
    _rightView = [[WJAudioBelowView alloc]initWithFrame:CGRectMake(35, 0, 0, 50)];
    _rightView.backgroundColor = [UIColor colorWithRed:29/255.0 green:29/255.0 blue:29/255.0 alpha:0.8];
    [_rightView.playBtn addTarget:self action:@selector(playBut:) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:_rightView];
    
    
    UIView *butView = [[UIView alloc]initWithFrame:CGRectMake(15, 5, 40, 40)];
    butView.backgroundColor = BSWhiteColor;
    butView.layer.cornerRadius = 20;
    [self addSubview:butView];

    _roatBut = [UIButton buttonWithType:UIButtonTypeCustom];
    _roatBut.frame = CGRectMake(-5, -5, 50, 50);
    [_roatBut setImage:[UIImage imageNamed:@"music"] forState:UIControlStateNormal];
    [_roatBut addTarget:self action:@selector(roatButClick:) forControlEvents:UIControlEventTouchUpInside];
    [butView addSubview:_roatBut];
    
    UIPanGestureRecognizer *panGestureRecongnizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGestureRecongnizer:)];
    [_roatBut addGestureRecognizer:panGestureRecongnizer];
}

-(void)handlePanGestureRecongnizer:(UIPanGestureRecognizer *)pan{
    CGPoint translationPoint = [pan translationInView:BSKeyWindow];
    CGPoint center = pan.view.center;
    pan.view.center = CGPointMake(center.x + translationPoint.x, center.y + translationPoint.y);
    [pan setTranslation:CGPointZero inView:BSKeyWindow];
}

- (CADisplayLink *)link {
    if (!_link) {
        // 创建定时器, 一秒钟调用rotation方法60次
        _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(rotation)];
        // 手动将定时器加入到事件循环中
        // NSRunLoopCommonModes会使得RunLoop会随着界面切换扔继续使用, 不然如果使用Default的话UI交互没问题, 但滑动TableView就会出现不转问题, 因为RunLoop模式改变会影响定时器调度
        [_link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    }
    return _link;
}


/**  背景图rotation滚动 */
- (void)rotation {
    self.roatBut.layer.transform = CATransform3DRotate(self.roatBut.layer.transform, angleToRadian(1), 0, 0, 1);
}

- (void)roatButClick:(UIButton *)but {
    but.selected = !but.isSelected;
    [UIView animateWithDuration:0.25 animations:^{
        if (but.selected) {
            _rightView.frame = CGRectMake(35, 0, WIDTH - 70, 50);
        } else {
            _rightView.frame = CGRectMake(35, 0, 0, 50);
        }
        [_rightView resetViewWithEnabled:but.selected];
    }];
}

- (void)playBut:(UIButton *)button {
    button.selected = !button.isSelected;
    if (button.selected) {
        [self.player pause];
        self.link.paused = YES;
    }else{
        [self.player play];
        self.link.paused = false;
    }
}

- (void)setModel:(Audio *)model {
    
//    if ([model.audio[0] isEqualToString:_strUrl]) return;
    
    _model = model;
    
    [[WJVideoPlayView sharedPlayView] resetAVPlayer];
    NSInteger min = model.duration / 60;
    NSInteger sec = model.duration % 60;
    _rightView.totalDurationLabel.text = [NSString stringWithFormat:@"%02zd:%02zd",min,sec];
    
    self.strUrl = model.audio[0];
    
    if (_player) {
        [_player pause];
        [self removeObserverFromPlayerItem:_playerItem];
        _playerItem = nil;
        _player = nil;
    }
    _playerItem = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:self.strUrl]];
    _player = [AVPlayer playerWithPlayerItem:_playerItem];
    
    [self addObserverToPlayItem:self.player.currentItem];
    
    [self.player play];
    
    self.link.paused = false;
}

///> 给playerItem添加监控对象  KVO
- (void)addObserverToPlayItem:(AVPlayerItem *)playerItem {
    //监控状态属性: 注意AVPlayer也有一个status属性,通过监控它的status也可以获得播放状态
    [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    //监控网络加载情况属性
    [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    AVPlayerItem *playerItem = object;
    if ([keyPath isEqualToString:@"status"]) {
        AVPlayerStatus status = [[change objectForKey:@"new"] intValue];
        if (status == AVPlayerStatusReadyToPlay) {
            //添加各种通知和观察者
            [self addNotification];
            [self addProgressObserver];
            [self addSliderTarget];
        }
    } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {  //缓存的时间
        NSArray *array = playerItem.loadedTimeRanges;
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次缓存时间范围
        float startSeconds = CMTimeGetSeconds(timeRange.start);
        float durationSeconds = CMTimeGetSeconds(timeRange.duration);
        NSTimeInterval totalBuffer = startSeconds + durationSeconds;
        self.rightView.timeIntervalProgress.progress = totalBuffer / self.model.duration;
    }
}

#pragma mark - 播放器通知
- (void)addNotification {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}

- (void)playbackFinished:(NSNotification *)notification {
    [_rightView.playBtn sendActionsForControlEvents:UIControlEventTouchUpInside];
    [self.player seekToTime:kCMTimeZero];
    self.rightView.progressSlider.value = 0;
}

#pragma mark - 播放进度监控
/**
 *	进度条监控  当前的时间
 */
- (void)addProgressObserver {
    __block typeof(self) weakSelf = self;
    _progressObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        float current = CMTimeGetSeconds(time);
        NSString *str = [NSString stringWithFormat:@"%.0f",current];
        NSInteger min = str.integerValue / 60;
        NSInteger sec = str.integerValue % 60;
        weakSelf.rightView.progressSlider.value = current;
        weakSelf.rightView.currentTimeLabel.text = [NSString stringWithFormat:@"%02zd:%02zd",min,sec];
    }];
}

- (void)addSliderTarget {
    self.rightView.progressSlider.maximumValue = self.model.duration;
    self.rightView.progressSlider.minimumValue = 0;
    [self.rightView.progressSlider addTarget:self action:@selector(beginHandleSlider:) forControlEvents:UIControlEventTouchDragInside];
    [self.rightView.progressSlider addTarget:self action:@selector(endHandleSlider:) forControlEvents:UIControlEventValueChanged];
}

- (void)beginHandleSlider:(UISlider *)slider {
    AVPlayerItem *playerItem = self.player.currentItem;
    float total = CMTimeGetSeconds(playerItem.duration);
    float current = slider.value * total;
    [self.player seekToTime:CMTimeMakeWithSeconds(current, playerItem.duration.timescale)];
    [self.player pause];
}


- (void)endHandleSlider:(UISlider *)slider {
    [self.player play];
}


- (void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem {
    [playerItem removeObserver:self forKeyPath:@"status"];
    [playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
}
@end
